import re
import time
import requests
import multiprocessing
# import asyncio
import json
from requests_toolbelt import MultipartEncoder
from frame_work.type_file import (
    ModShowSource,
    ModShowType
)
from frame_work.setting import *
from frame_work.logger import Logger
from frame_work.util import (
    change_user_account_status,
    get_binded_shop_list,
    bind_shop,
    get_order_url,
    assert_result_dict,
    get_now_time
)
from frame_work.login import PcLogin
from workspace.shikee.chuji.pay import PayQuantity
# from frame_work.d_redis import MyRedis
from frame_work.yaml_file import YAML
from frame_work.release_util import modshow_release

logger = Logger(__name__).get_logger()


class Activity(object):

    def __init__(self, uname):
        self.uname = uname
        self.session = self.get_session()
        self.pay = PayQuantity(self.session)
        self.tids = []
        self.nums = 0
        self.fail_nums = 0
        self.yaml = YAML(os.path.join(base_Dir, 'data', 'data.yaml'))

    def get_session(self):
        """
        :return:返回登录session
        """
        login = PcLogin(self.uname)
        # login = PcLogin('user0637')
        login.pc_login()
        return login.get_session()

    def get_html(self):
        """
        请求一个页面，在响应中获取比如：token，shopId等
        :return: html
        """
        url = self.yaml.get_data("token").get('url')
        html = self.session.get(url).text
        return html

    def get_token(self):
        """
        从html中通过正则表达式获取token
        :return:token
        """
        complex_value = 'name="token" value="(.*?)"'
        html = self.get_html()
        token = re.findall(complex_value, html)
        try:
            token = token[0]
            logger.debug('获取token值 => %s ...' % token)
        except (IndexError, KeyError) as e:
            logger.debug("获取token出错")
            return False
        else:
            return token

    def echo_pic(self, num):
        """
        发布活动中会含有上传图片的操作，此函数在作用post多张图片到图片服务器，获取tmp address类似：tmp/2019/08/20/08500820924072552490.jpg
        :param num:图片数量
        :return:pics 数组
        """
        pics = []
        for index in range(0, num):
            shikee_cookies = self.session.cookies.get(
                'shikee')  # 获取用户cookies中的shikee部分
            yaml_data = self.yaml.get_data("echo_tmp_pic_address")
            yaml_data.get('data').update({
                'id': 'WU_FILE_' + str(index),  # num:发布活动页面有多个上传图片地方,用于区别
                'Filedata': (
                'filename', open(os.path.join(image_Path, '模特秀' + str(index + 1) + '.jpg'), 'rb'), 'image/jpg')
            })
            m = MultipartEncoder(
                fields=yaml_data.get('data')
            )
            r = requests.post(yaml_data.get('url') + '/1?swf_upload_cookie=' + shikee_cookies, data=m,
                              headers={'Content-Type': m.content_type})
            pics.append(json.loads(r.text).get('data'))
        return pics

    @staticmethod
    def echo_options(val):
        """
        列出活动来源,用户自己选择
        :return:source
        """
        for index, i in enumerate(val.value, start=1):
            print(index, ''.join(list(i.keys())))
        try:
            choise_source = int(input("请选择活动来源选项:\t\n---->  "))
        except BaseException as e:
            logger.error('输入选项错误，请选择对应序号')
        else:
            if choise_source > len(val.value):
                logger.error('超出选项范围')
                return False
            else:
                source = list(
                    val.value[choise_source - 1].values())
                # [数组形式]
                return source[0]

    def release_basic(self, *args, **kwargs):
        """
        发布封装
        :param args:
        :param kwargs:
        :return:
        """
        source = kwargs.get("source")
        source_cn = ModShowSource(source).name  # 枚举类通过value反向获取name
        source_cn = '淘特' if source_cn == '淘宝特价版' else source_cn
        value = get_binded_shop_list(self.uname, source_cn)
        if not value:
            bind_shop(source_cn, self.uname)
            value = get_binded_shop_list(self.uname, source_cn)
        title = ModShowType(kwargs.get("type")).name + '_' + source_cn + '_刘' + get_now_time()
        order_url = get_order_url(ModShowSource(source).name)
        pics = self.echo_pic(6)
        url, post_data, header = modshow_release(
            type=kwargs.get("type"),
            title_pic=pics[0],
            reference_imgs_0=pics[0:3],
            reference_imgs_1=pics[3:6],
            source=source, token=self.get_token(),
            shopId=value[0].get("sid"),
            shop_name=value[0].get("name"),
            Title=title,
            url_order=order_url
        )
        logger.debug('开始发布' + source_cn + '_模特秀活动')
        response = self.session.post(url, data=post_data, headers=header).text
        status = assert_result_dict(
            response, self.uname + '模特秀活动 《' + title + "》 来源：" + source_cn + " ")
        if status:
            self.nums += 1
            self.tids.append(json.loads(response).get(
                "data").split('/')[-1])  # 发布成功的tid加到数组
            logger.info("提示：接口限制活动发布时间间隔在30s以上,请等待30S......")
            time.sleep(30)  # logger.info("提示：活动发布时间间隔在25s以上,发布成功之后请等待25s在发布下一个......")
        else:
            self.fail_nums += 1

    def release_activity(self):
        """
        发布模特秀批量活动
        :return:
        """
        num = int(input(u'请输入模特秀发布数量: '))
        type = self.echo_options(ModShowType.type)
        source = self.echo_options(ModShowSource.source)
        while True:
            self.release_basic(type=type, source=source)
            if self.nums == num or self.fail_nums == 2:
                break

    def pay_money(self):
        """
        支付活动款 [ 多进程处理 ]
        :return:
        """
        cpu_count = multiprocessing.cpu_count()
        pool = multiprocessing.Pool(cpu_count)
        pool.map(self.pay.test_pay_quantity, self.tids)


def run():
    while True:
        seller_uname = input(u'请输入要批量发布的商家用户名(按Q|q返回上一目录): ')
        if seller_uname in ('q', 'Q'):
            break
        status = change_user_account_status(seller_uname)
        if not status:
            break
        activity = Activity(seller_uname)
        activity.release_activity()
        activity.pay_money()
        # task_list = []
        # task = asyncio.create_task(activity.release_activity())
        # task1 = asyncio.create_task(activity.release_activity())
        # task_list.append(task)
        # task_list.append(task1)
        # results = await asyncio.gather(*task_list)

# def main(fuc):
#     loop = asyncio.get_event_loop()
#     loop.run_until_complete(fuc)


if __name__ == "__main__":
    # activity = Activity('user0637')
    # main(activity.pay)
    # activity.release_activity()
    # asyncio.run(activity.main())
    run()
    # activity.pay_money()
